/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package technotheist.data.clbuffer;

import com.nativelibs4java.opencl.CLBuffer;
import org.bridj.Pointer;
import technotheist.data.BBuffer;

/**
 *
 * @author Mitch
 * @param <T>
 */
public abstract class OCLBuffer<T extends Number> extends BBuffer<T> {
    private final CLBufferManager mngr;
    private final CLBuffer<T> buffer;
    private final Pointer<T> ptr;
    private boolean hostDirty;
    private boolean deviceDirty;
    private final int size;

    public OCLBuffer(CLBufferManager mngr, Pointer<T> ptr, int size) {
	this.size = size;
	this.mngr = mngr;
	this.ptr = ptr;
	this.buffer = mngr.createBuffer(ptr, size);
    }

    @Override
    public T s(int index) {
	checkHost();
	return ptr.get(index);
    }

    @Override
    public void s(int index, T v) {
	checkHost();
	ptr.set(index, v);
	deviceDirty = true;
    }

    public CLBuffer<T> read() {
	checkDevice();
	return buffer;
    }

    public CLBuffer<T> write() {
	checkDevice();
	hostDirty = true;
	return buffer;
    }

    private void checkHost() {
	if (hostDirty) {
	    mngr.read(ptr, buffer);
	    hostDirty = false;
	}
    }

    private void checkDevice() {
	if (deviceDirty) {
	    mngr.write(ptr, buffer);
	    deviceDirty = false;
	}
    }

    @Override
    public int size() {
	return size;
    }
    
}
